﻿Imports System.IO
Public Class batchHandBrake

    Dim optionStrings(100) As String, optionStringCNT As Integer
    Dim parmSource As String, currOptionName As String

    ' screen sizing variables

    Dim formHeight As Integer, formWidth As Integer
    Dim optionTextWidth As Integer, fileNamesWidth As Integer, fileNamesHeight As Integer

    Dim changingOptionText As Boolean

    Dim processesToUseTMP As Integer

    ' process arrays

    Dim psi(100) As System.Diagnostics.ProcessStartInfo
    Dim prc(100) As System.Diagnostics.Process
    Dim prcStarted(100) As Boolean
    Dim processesToUse As Integer


    Private Sub batchHandBrake_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed

        Call saveParameters()

    End Sub

    Private Sub setFormCaption(ByVal inText As String)
        Dim extraText As String

        extraText = ""
        If procFolder.Text <> "" Then
            extraText = " - " & procFolder.Text
        End If

        If inText <> "" Then
            extraText = extraText & " - " & inText
        End If

        Me.Text = "batchHandBrake - V" & Reflection.Assembly.GetExecutingAssembly.GetName.Version.Major & "." & Reflection.Assembly.GetExecutingAssembly.GetName.Version.Minor & "." & Reflection.Assembly.GetExecutingAssembly.GetName.Version.Revision & extraText

    End Sub

    Private Sub batchHandBrake_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' set up statusstrip

        ToolStripStatusLabel1.Text = "Starting ......"

        ' establish how much of the machine to monopolise (default to num processors - 2) or 1 whichever is greater

        processesToUseTMP = Environment.ProcessorCount - 2
        If processesToUseTMP = 0 Then
            processesToUseTMP = 1
        End If

        ' Initialise variables
        formHeight = Me.Height
        formWidth = Me.Width
        optionTextWidth = optionText.Width
        fileNamesWidth = fileNames.Width
        fileNamesHeight = fileNames.Height

        changingOptionText = False

        Call GetParameters()

        If mnuprocessesToUse.Text = "<not set>" Then
            mnuprocessesToUse.Text = processesToUseTMP
        End If

        If optionBox.Items.Count > 0 Then
            If optionBox.SelectedIndex = -1 Then
                optionBox.SelectedIndex = 0
            End If
        End If

        ToolStripStatusLabel1.Text = ""

        Call setFormCaption("")

        Call TextBox1_TextChanged(sender, e)

    End Sub

    Private Sub SetParm_Value(ByVal pl As String, ByVal eq_pos As Integer)
        Dim parm_name As String

        '
        ' process those parameters that have an equal sign in them
        '
        parm_name = UCase(Trim(Strings.Left(pl, eq_pos - 1)))
        Select Case parm_name
            Case Is = "SOURCE_DIR"
                On Error GoTo drive_err
                FolderBrowserDialog1.SelectedPath = Trim(Mid(pl, eq_pos + 1))
                On Error GoTo 0
                procFolder.Text = FolderBrowserDialog1.SelectedPath
                Call refreshFileNames()
                parmSource = parmSource & "SOURCE_DIR=" & FolderBrowserDialog1.SelectedPath & vbCrLf
            Case Is = "TARGET_DIR"
                targetDir.Text = Trim(Mid(pl, eq_pos + 1))
                On Error GoTo drive_err
                FolderBrowserDialog1.SelectedPath = Trim(Mid(pl, eq_pos + 1))
                On Error GoTo 0
                procFolder.Text = FolderBrowserDialog1.SelectedPath
                parmSource = parmSource & "TARGET_DIR=" & FolderBrowserDialog1.SelectedPath & vbCrLf
            Case Is = "CLI_LOC"
                handbrakeLoc.Text = Trim(Mid(pl, eq_pos + 1))
                On Error GoTo drive_err
                FolderBrowserDialog1.SelectedPath = Trim(Mid(pl, eq_pos + 1))
                On Error GoTo 0
                handbrakeLoc.Text = FolderBrowserDialog1.SelectedPath
                If Not System.IO.File.Exists(handbrakeLoc.Text & "\HandBrakeCLI.exe") = True Then
                    MsgBox("HandBrakeCLI.exe not found in " & handbrakeLoc.Text & vbCrLf & "SO defaulting to install directory", MsgBoxStyle.OkOnly, "HandBrakeCLI.exe NOT found")
                    ' CLI doesn't exist there so just default to an existing dir .....
                    handbrakeLoc.Text = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
                End If

                parmSource = parmSource & "CLI_LOC=" & FolderBrowserDialog1.SelectedPath & vbCrLf
            Case Is = "ESCAPECHAR"
                mnuEscapeCharacterValue.Text = Trim(Mid(pl, eq_pos + 1))
                parmSource = parmSource & "ESCAPECHAR=" & mnuEscapeCharacterValue.Text & vbCrLf
            Case Is = "NUM_PROCESSES"
                mnuprocessesToUse.Text = Trim(Mid(pl, eq_pos + 1))
                parmSource = parmSource & "NUM_PROCESSES=" & mnuprocessesToUse.Text & vbCrLf
            Case Is = "GENSUFF"
                mnuGenSuff.Text = Trim(Mid(pl, eq_pos + 1))
                parmSource = parmSource & "GENSUFF=" & mnuEscapeCharacterValue.Text & vbCrLf
            Case Is = "OPTIONNAME"
                optionBox.Items.Add(Trim(Mid(pl, eq_pos + 1)))
                optionStringCNT = optionStringCNT + 1
                optionStrings(optionStringCNT) = ""
                parmSource = parmSource & "OPTIONNAME=" & Trim(Mid(pl, eq_pos + 1)) & vbCrLf
            Case Is = "OPTIONSTRING"
                optionStrings(optionStringCNT) = Trim(Mid(pl, eq_pos + 1))
                parmSource = parmSource & "OPTIONSTRING=" & Trim(Mid(pl, eq_pos + 1)) & vbCrLf
            Case Is = "SELECTED_OPTION"
                optionBox.SelectedIndex = Val(Trim(Mid(pl, eq_pos + 1)))
                parmSource = parmSource & "SELECTED_OPTION=" & Trim(Mid(pl, eq_pos + 1)) & vbCrLf
            Case Else
                MsgBox("Unknown parameter : " & parm_name)
        End Select

        Exit Sub

drive_err:
        FolderBrowserDialog1.SelectedPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
        MsgBox("Folder " & Trim(Mid(pl, eq_pos + 1)) & " not found." & vbCrLf & FolderBrowserDialog1.SelectedPath & " substituted")
        Resume Next

    End Sub
    Sub SetParm_Option(ByVal parm_line As String)
        '
        ' Process those parameters that done have any assignment
        '
        parmSource = parmSource & Strings.Left(Trim(parm_line), 20) & vbCrLf

        Select Case UCase(Strings.Left(Trim(parm_line), 20))
            Case Is = "REVERSE_SELECTION"
                reverseSelection.Checked = True
            Case Is = "KEEP_SELECTION"
                reverseSelection.Checked = False
            Case Is = "DISPLAY_ONLY"
                DisplayCommandOnly.Checked = True
            Case Is = "EXECUTE"
                DisplayCommandOnly.Checked = False
            Case Is = "CASE_SENSITIVE"
                caseSensitive.Checked = True
            Case Is = "CASE_INSENSITIVE"
                caseSensitive.Checked = False
            Case Else
        End Select

    End Sub

    Sub GetParameters()
        Dim trimmed_line As String
        Dim parm_error As Boolean, parm_line As String, eq_pos As Integer

        If Not System.IO.File.Exists(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location()) & "\batchHandBrake.ini") = True Then
            ' file doesn't exist so create it .....
            Dim createFile As System.IO.FileStream
            createFile = System.IO.File.Create(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location()) & "\batchHandBrake.ini")
            createFile.Close()
        End If
        Dim iniReader As New StreamReader(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location()) & "\batchHandBrake.ini")

        parm_error = False

        ' set defaults
        If Not System.IO.File.Exists("c:\Program Files\Handbrake\HandBrakeCLI.exe") = True Then
            ' CLI doesn't exist there so just default to an existing dir .....
            handbrakeLoc.Text = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
        Else
            handbrakeLoc.Text = "c:\Program Files\Handbrake"
        End If

        optionStringCNT = -1

        procFolder.Text = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
        targetDir.Text = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
        FolderBrowserDialog1.SelectedPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
        mnuEscapeCharacterValue.Text = "\"

        Do While iniReader.Peek <> -1
            parm_line = iniReader.ReadLine()
            trimmed_line = Trim(parm_line)
            eq_pos = InStr(trimmed_line, "=")
            If eq_pos <> 0 Then ' parm of the form A=B
                Call SetParm_Value(parm_line, eq_pos)
            Else ' parm not of the form A=B
                Call SetParm_Option(parm_line)
            End If
        Loop

        iniReader.Close()

    End Sub


    Private Sub saveParameters()

        Dim i As Integer

        If Not System.IO.File.Exists(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location()) & "\batchHandBrake.ini") = True Then
            ' file doesn't exist so create it .....
            Dim createFile As System.IO.FileStream
            createFile = System.IO.File.Create(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location()) & "\batchHandBrake.ini")
        End If

        ' file is now guaranteed to exist (probably)
        Dim iniWriter As New StreamWriter(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location()) & "\batchHandBrake.ini")

        iniWriter.WriteLine("TARGET_DIR=" & targetDir.Text)
        iniWriter.WriteLine("SOURCE_DIR=" & procFolder.Text)
        iniWriter.WriteLine("CLI_LOC=" & handbrakeLoc.Text)
        iniWriter.WriteLine("ESCAPECHAR=" & mnuEscapeCharacterValue.Text)
        iniWriter.WriteLine("GENSUFF=" & mnuGenSuff.Text)
        iniWriter.WriteLine("NUM_PROCESSES=" & mnuprocessesToUse.Text)

        If (caseSensitive.Checked) Then
            iniWriter.WriteLine("CASE_SENSITIVE")
        Else
            iniWriter.WriteLine("CASE_INSENSITIVE")
        End If

        If (reverseSelection.Checked) Then
            iniWriter.WriteLine("REVERSE_SELECTION")
        Else
            iniWriter.WriteLine("KEEP_SELECTION")
        End If

        If (DisplayCommandOnly.Checked) Then
            iniWriter.WriteLine("DISPLAY_ONLY")
        Else
            iniWriter.WriteLine("EXECUTE")
        End If

        For i = 0 To optionBox.Items.Count - 1
            iniWriter.WriteLine("OPTIONNAME=" & optionBox.Items.Item(i).ToString)
            iniWriter.WriteLine("OPTIONSTRING=" & optionStrings(i))
        Next

        iniWriter.WriteLine("SELECTED_OPTION=" & Trim(Str(optionBox.SelectedIndex)))

        iniWriter.Close()

    End Sub

    Private Sub fndDir_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fndDir.Click
        Dim MyFolderBrowser As New System.Windows.Forms.FolderBrowserDialog

        ' Description that displays above the dialog box control.

        MyFolderBrowser.Description = "Select the Folder to be processed"
        ' Sets the root folder where the browsing starts from
        MyFolderBrowser.RootFolder = Environment.SpecialFolder.MyComputer

        Dim dlgResult As DialogResult = MyFolderBrowser.ShowDialog()

        If dlgResult = Windows.Forms.DialogResult.OK Then
            procFolder.Text = MyFolderBrowser.SelectedPath
        End If

        Call refreshFileNames()

        Call TextBox1_TextChanged(sender, e) ' re select files

    End Sub

    Private Sub refreshFileNames()
        Dim dirLen As Integer

        dirLen = procFolder.Text.Length
        fileNames.Items.Clear() ' clear all of the file names

        For Each fName As String In My.Computer.FileSystem.GetFiles(procFolder.Text)
            If dirLen = 3 Then ' special case when at the root dir (i.e. c:\ or d:\)
                fileNames.Items.Add(fName.Substring(dirLen))
            Else
                fileNames.Items.Add(fName.Substring(dirLen + 1))
            End If
        Next

    End Sub

    Private Sub fndHandBrakeLoc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fndHandBrakeLoc.Click
        Dim MyFolderBrowser As New System.Windows.Forms.FolderBrowserDialog

        ' Description that displays above the dialog box control.

        MyFolderBrowser.Description = "Select the Folder containing HandBrakeCLI.exe"
        ' Sets the root folder where the browsing starts from
        MyFolderBrowser.RootFolder = Environment.SpecialFolder.MyComputer

        Dim dlgResult As DialogResult = MyFolderBrowser.ShowDialog()

        If dlgResult = Windows.Forms.DialogResult.OK Then

            If Not System.IO.File.Exists(MyFolderBrowser.SelectedPath & "\HandBrakeCLI.exe") = True Then
                MsgBox("HandBrakeCLI.exe not found in " & MyFolderBrowser.SelectedPath & vbCrLf & "So defaulting to install directory", MsgBoxStyle.OkOnly, "HandBrakeCLI.exe NOT found")
                ' CLI doesn't exist there so just default to an existing dir .....
                handbrakeLoc.Text = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly.Location())
            Else
                handbrakeLoc.Text = MyFolderBrowser.SelectedPath
            End If

        End If

    End Sub

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles searchPattern.TextChanged
        Dim searchStr As String, searchFileName As String, searchStarted As Boolean
        Dim noEVal As Boolean, selCount As Integer
        searchStarted = True
        noEVal = True
        selCount = 0
        For i = 0 To fileNames.Items.Count - 1
            Application.DoEvents()
            searchStr = searchPattern.Text
            searchFileName = fileNames.Items.Item(i).ToString
            If Not caseSensitive.Checked Then
                searchStr = UCase(searchPattern.Text)
                searchFileName = UCase(fileNames.Items.Item(i).ToString)
            End If

            If testSelection(searchStr, searchFileName) Then ' it's a match
                If reverseSelection.Checked Then ' if select those NOT matched
                    fileNames.SetSelected(i, False)
                Else
                    fileNames.SetSelected(i, True)
                End If
            Else ' it wasn't a match
                If reverseSelection.Checked Then ' if select those NOT matched
                    fileNames.SetSelected(i, True)
                Else
                    fileNames.SetSelected(i, False)
                End If

            End If
        Next i
        noEVal = False

        searchStarted = False

        selCount = fileNames.SelectedIndices.Count
        Call setFormCaption("Files Selected :" & Str(selCount) & " of " & Str(fileNames.Items.Count))

        ToolStripStatusLabel1.Text = "Files Selected :" & Str(selCount) & " of " & Str(fileNames.Items.Count)

    End Sub

    Private Function testSelection(ByVal inPattern As String, ByVal inFileName As String) As Boolean
        Dim currPattern As String, currFileName As String
        Dim currPattPos As Integer, currFNPos As Integer
        Dim waitingFor As String, special As String
        Dim lastPos As Integer

        testSelection = False
        waitingFor = ""

        currPattPos = 1
        currFNPos = 1
        currPattern = Mid(inPattern, currPattPos, 1)
        currFileName = Mid(inFileName, currFNPos, 1)

        If Len(inPattern) > 2 And _
           Strings.Left(inPattern, 2) = "*." And _
           InStr(3, inPattern, ".") = 0 And _
           InStr(3, inPattern, "*") = 0 And _
           InStr(inFileName, ".") > 0 Then ' we'll select all with this suffix ....
            If Mid(inFileName, InStrRev(inFileName, ".") + 1) = Mid(inPattern, 3) Then
                testSelection = True
                Exit Function
            End If
        End If

        special = ""
        If currPattern = "*" Then
            If currPattPos = Len(inPattern) Then
                testSelection = True
                Exit Function
            End If
            special = "*"
            waitingFor = Mid(inPattern, currPattPos + 1, 1)
        ElseIf currPattern = "." Then
            special = "."
        ElseIf currPattern = mnuEscapeCharacterValue.Text Then
            If currPattPos <> Len(inPattern) Then
                currPattPos = currPattPos + 1
                currPattern = Mid(inPattern, currPattPos, 1)
            End If
        End If

        lastPos = currPattPos

        For i = 1 To Len(inFileName)
            If special = "." Then
                currPattPos = currPattPos + 1
            ElseIf special = "*" Then
                If Mid(inFileName, i, 1) = waitingFor Then
                    currPattPos = currPattPos + 2
                End If
            Else ' just do the checking ...
                If currPattern <> Mid(inFileName, i, 1) Then
                    testSelection = False
                    Exit Function
                End If
                currPattPos = currPattPos + 1
            End If

            ' reset the next pattern char if necessary
            If currPattPos <> lastPos Then
                lastPos = currPattPos
                currPattern = Mid(inPattern, currPattPos, 1)

                special = ""
                If currPattern = "*" Then
                    If currPattPos = Len(inPattern) Then
                        testSelection = True
                        Exit Function
                    End If
                    special = "*"
                    waitingFor = Mid(inPattern, currPattPos + 1, 1)
                ElseIf currPattern = "." Then
                    special = "."
                ElseIf currPattern = mnuEscapeCharacterValue.Text Then
                    If currPattPos <> Len(inPattern) Then
                        currPattPos = currPattPos + 1
                        currPattern = Mid(inPattern, currPattPos, 1)
                    End If
                End If
            End If

        Next i

        If currPattPos = Len(inPattern) + 1 Then
            testSelection = True
        End If

    End Function

    Private Sub findTargetDir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles findTargetDir.Click
        Dim MyFolderBrowser As New System.Windows.Forms.FolderBrowserDialog

        ' Description that displays above the dialog box control.

        MyFolderBrowser.Description = "Select the Folder to place all of the generated files in"
        ' Sets the root folder where the browsing starts from
        MyFolderBrowser.RootFolder = Environment.SpecialFolder.MyComputer
        Dim dlgResult As DialogResult = MyFolderBrowser.ShowDialog()

        If dlgResult = Windows.Forms.DialogResult.OK Then
            targetDir.Text = MyFolderBrowser.SelectedPath
        End If
    End Sub

    Private Sub mnuEscapeCharacterValue_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuEscapeCharacterValue.Click
        Dim x As String
        x = InputBox("Enter Escape Character", "New Escape Character", mnuEscapeCharacterValue.Text)
        mnuEscapeCharacterValue.Text = Strings.Left(x & " ", 1)
    End Sub

    Private Sub saveOptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles saveOptions.Click

        ' Add the name into the drop down list
        optionBox.Items.Add(optionName.Text)
        optionName.Text = ""

        optionStringCNT = optionStringCNT + 1
        optionStrings(optionStringCNT) = optionText.Text
        ' now get rid of CRs and LFs
        optionStrings(optionStringCNT).Replace(vbCr, " ")
        optionStrings(optionStringCNT).Replace(vbLf, " ")

    End Sub

    Private Sub batchHandBrake_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        Call Form_Resize()
    End Sub

    Private Sub Form_Resize()

        If formHeight = 0 Then Exit Sub ' ignore the first call to this routine (prior ro the load event)

        If Me.WindowState <> FormWindowState.Minimized Then

            ' dont allow a resize to smaller than the start size
            If Me.Width < formWidth Then Me.Width = formWidth
            If Me.Height < formHeight Then Me.Height = formHeight

            ' adjust the affected entries ....
            fileNames.Height = Me.Height - (formHeight - fileNamesHeight)
            fileNames.Width = Me.Width - (formWidth - fileNamesWidth)
            optionText.Width = Me.Width - (formWidth - optionTextWidth)

        End If
    End Sub

    Private Sub reverseSelection_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles reverseSelection.CheckedChanged
        ' Call TextBox1_TextChanged(sender, e)
        Dim i As Integer

        For i = 0 To fileNames.Items.Count - 1
            If fileNames.GetSelected(i) Then ' it's selected
                fileNames.SetSelected(i, False)
            Else ' it's not selected
                fileNames.SetSelected(i, True)
            End If
        Next

    End Sub

    Private Sub caseSensitive_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles caseSensitive.CheckedChanged
        Call TextBox1_TextChanged(sender, e)
    End Sub

    Private Sub optionBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optionBox.SelectedIndexChanged
        optionText.Text = optionStrings(optionBox.SelectedIndex)
    End Sub

    Private Sub startProcessing_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles startProcessing.Click
        Dim i As Integer, x As String, j As Integer, processorNotFree As Boolean, k As Integer
        Dim fileStem As String, processorNotAllFree As Boolean
        Dim activeCount As Integer

        If fileNames.SelectedIndices.Count = 0 Then
            MsgBox("No files have been selected for processing")
            Exit Sub
        End If

        ' set processes variable to make sure it doesn't change
        processesToUse = Val(mnuprocessesToUse.Text)

        ' mark all processors as free

        For k = 0 To processesToUse - 1
            prcStarted(k) = False
        Next k

        ' Process each selected entry ....
        For Each i In fileNames.SelectedIndices

            If (InStr(fileNames.Items(i), ".") > 0) Then ' there is at least 1 period
                fileStem = Strings.Left(fileNames.Items(i), InStrRev(fileNames.Items(i), ".") - 1)
            Else
                fileStem = fileNames.Items(i)
            End If

            If DisplayCommandOnly.Checked Then
                x = InputBox("Generated Command:", "HandBrake Command", "cmd.exe /c """ & handbrakeLoc.Text & "\HandBrakeCLI.exe"" " & _
                              " -i """ & procFolder.Text & "\" & fileNames.Items(i) & """" & _
                              " -o """ & targetDir.Text & "\" & fileStem & "." & mnuGenSuff.Text & """ " & _
                              optionText.Text _
                     )
            Else
                ' load up the available processes .....

                ' look for a free process .....
                processorNotFree = True
                While processorNotFree
                    For j = 0 To processesToUse - 1
                        If Not prcStarted(j) Then
                            processorNotFree = False
                            Exit For
                        End If
                    Next j
                    Me.Refresh()
                    If processorNotFree Then
                        For l As Integer = 0 To 240 ' wait for 60 secs but wake up every 1/4 secs to adjust things
                            System.Threading.Thread.Sleep(250) ' wait for 1/4 secs and then check all of the processes
                            Me.Refresh()
                            Application.DoEvents()
                        Next l
                        For k = 0 To processesToUse - 1
                            If prcStarted(k) Then
                                If prc(k).HasExited Then
                                    prcStarted(k) = False
                                End If
                            End If
                        Next k
                    End If
                End While

                ' to get here there should be a processor free and it's index should be j

                psi(j) = New System.Diagnostics.ProcessStartInfo()
                With psi(j)
                    .Arguments = " -i """ & procFolder.Text & "\" & fileNames.Items(i) & """" & _
                                 " -o """ & targetDir.Text & "\" & fileStem & "." & mnuGenSuff.Text & """ " & _
                                 optionText.Text
                    .FileName = handbrakeLoc.Text & "\HandBrakeCLI.exe"
                End With

                prc(j) = New System.Diagnostics.Process()
                With prc(j)
                    .StartInfo = psi(j)
                End With
                prc(j).Start()
                prcStarted(j) = True
            End If
            ToolStripStatusLabel1.Text = "Now processing " & fileNames.Items(i)
            statusStrip1.Refresh()

        Next

        ' wait until the last process has finished .....

        processorNotAllFree = True
        While processorNotAllFree
            processorNotAllFree = False
            activeCount = 0
            For j = 0 To processesToUse - 1
                If prcStarted(j) Then
                    processorNotAllFree = True
                    activeCount += 1
                End If
            Next j
            Me.Refresh()
            If processorNotAllFree Then
                For l As Integer = 0 To 240 ' wait for 60 secs but wake up every 1/4 secs to adjust things
                    System.Threading.Thread.Sleep(250) ' wait for 1/4 secs and then check all of the processes
                    Me.Refresh()
                    Application.DoEvents()
                Next l
                For k = 0 To processesToUse - 1
                    If prcStarted(k) Then
                        If prc(k).HasExited Then
                            prcStarted(k) = False
                        End If
                    End If
                Next k
            End If
            ToolStripStatusLabel1.Text = "Waiting for " & Str(activeCount) & " processes to finish"
            statusStrip1.Refresh()
        End While

        ToolStripStatusLabel1.Text = "All Processing now compete"
        statusStrip1.Refresh()

    End Sub

    Private Sub mnuGenSuff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuGenSuff.Click
        Dim x As String
        x = InputBox("Enter the suffix to be generated", "New File Suffix", mnuGenSuff.Text)
        mnuGenSuff.Text = x
    End Sub

    Private Sub fileNames_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fileNames.SelectedIndexChanged
        Call setFormCaption("Files Selected :" & Str(fileNames.SelectedIndices.Count) & " of " & Str(fileNames.Items.Count))

        ToolStripStatusLabel1.Text = "Files Selected :" & Str(fileNames.SelectedIndices.Count) & " of " & Str(fileNames.Items.Count)
    End Sub

    Private Sub optionText_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optionText.TextChanged
        ' remove the -i, -o and HandBrakeCLI.exe parameters ......

        If Len(optionText.Text) = 0 Then Exit Sub

        If changingOptionText Then Exit Sub ' ignore changes made in this routine

        changingOptionText = True

        ' it uses a simple string matching algorithm, allowing no duplicates and no escape characters

        Dim maxParms As Integer, parmArray(100) As String
        Dim currPos As Integer, currToken As String
        Dim newParms As String

        currPos = 1
        currToken = ""
        maxParms = -1

        ' get the first space delimited parameter

        While currPos <= Strings.Len(optionText.Text) - 1
            If Mid(optionText.Text, currPos, 1) = " " Then
                If currToken <> "" Then ' save the token
                    maxParms = maxParms + 1
                    parmArray(maxParms) = currToken
                    currToken = ""
                End If
            ElseIf Mid(optionText.Text, currPos, 1) = """" Then ' skip till the next double quote
                currToken = currToken & Mid(optionText.Text, currPos, 1)
                currPos = currPos + 1 ' move to the next char
                While (currPos <= Strings.Len(optionText.Text) - 1) And (Mid(optionText.Text, currPos, 1) <> """")
                    currToken = currToken & Mid(optionText.Text, currPos, 1)
                    currPos = currPos + 1 ' move to the next char
                End While
                If currPos <= Strings.Len(optionText.Text) - 1 Then
                    currToken = currToken & Mid(optionText.Text, currPos, 1) ' adds the quote if necessary
                End If
                ' and then pretend that a space has been found ....
                maxParms = maxParms + 1
                parmArray(maxParms) = currToken
                currToken = ""
            ElseIf Mid(optionText.Text, currPos, 1) = "'" Then ' skip till the next single quote
                currToken = currToken & Mid(optionText.Text, currPos, 1)
                currPos = currPos + 1 ' move to the next char
                While currPos <= Strings.Len(optionText.Text) - 1 And Mid(optionText.Text, currPos, 1) <> "'"
                    currToken = currToken & Mid(optionText.Text, currPos, 1)
                    currPos = currPos + 1 ' move to the next char
                End While
                If currPos <= Strings.Len(optionText.Text) - 1 Then
                    currToken = currToken & Mid(optionText.Text, currPos, 1) ' adds the quote if necessary
                End If
                ' and then pretend that a space has been found ....
                maxParms = maxParms + 1
                parmArray(maxParms) = currToken
                currToken = ""
            Else
                currToken = currToken & Mid(optionText.Text, currPos, 1)
            End If

            currPos = currPos + 1 ' move to the next char

        End While

        If Mid(optionText.Text, currPos, 1) <> " " Then
            currToken = currToken & Mid(optionText.Text, currPos, 1)
        End If

        If currToken <> "" Then ' save the token
            maxParms = maxParms + 1
            parmArray(maxParms) = currToken
            currToken = ""
        End If

        newParms = ""
        For i = 0 To maxParms
            If parmArray(i) = "-i" Or parmArray(i) = "-o" Then ' skip this value and the next one
                currToken = currToken & parmArray(i) & vbCrLf
                i = i + 1
            ElseIf InStr(parmArray(i), "HandBrakeCLI.exe") > 0 Then ' just skip this entry

            Else ' just re-create the parameter .....
                newParms = newParms & parmArray(i) & " "
            End If
            currToken = currToken & parmArray(i) & vbCrLf
        Next

        optionText.Text = newParms

        ' MsgBox("Parms: " & currToken)

        changingOptionText = False

    End Sub

    Private Sub mnuprocessesToUse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuprocessesToUse.Click
        Dim x As String
        x = InputBox("Enter the number of processes to use", "Number of Processors", mnuprocessesToUse.Text)
        If Val(x) > 0 Then
            If Val(x) <= 64 Then
                mnuprocessesToUse.Text = Str(Val(x))
            Else ' max of 64 processes
                mnuprocessesToUse.Text = "64"
            End If
        ElseIf Val(x) = 0 Then
            mnuprocessesToUse.Text = processesToUseTMP
        Else
            mnuprocessesToUse.Text = "1"
        End If
    End Sub

    Private Sub AboutToolStripMenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripItem.Click
        frmAbout.ShowDialog()
    End Sub

    Private Sub HelpToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelpToolStripItem.Click
        helpScreen.Activate()
        helpScreen.inputFile = "batchHandBrake.rtf"
        helpScreen.ShowDialog()
    End Sub

    Private Sub VersionInformationItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VersionInformationItem.Click
        helpScreen.Activate()
        helpScreen.inputFile = "batchHandBrakeVersHist.rtf"
        helpScreen.ShowDialog()
    End Sub
End Class
